import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
JDK动态代理,重点关注invoke 方法和newProxyInstance
* 1．定义一个接口以及实现类
2.自定义InvocationHandler接口的实现类，并重写invoke方法，在invoke方法中我们会调用原生方法（被代理类中的方法）并添加一些自
定义处理逻辑
3. 通过Proxy.newProxyInstance方法创建代理对象
JDK动态代理的致命缺点在于只能代理实现了接口的类，
而CGLIB刚好能解决这个问题
* */

class StarAgentHandler implements InvocationHandler {
   private Object target; //被代理真实对象
   public StarAgentHandler(Object target) {
       this.target = target;
   }

   //负责处理自定义逻辑，当我们的动态代理对象调用一个方法时，这个方法的调用就会被转发到这里
   //proxy:动态生成的代理类
   //method：与代理类对象调用的方法相对应
   //args ：当前 method方法的参数
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      System.out.println("Agent收到信");
      System.out.println("Agent检查信");
      //转发真实明星，需要使用反射来做
      Object result = method.invoke(target, args);

      System.out.println("Agent记录处理完成");
      //invoke方法需要有返回
      return result;
   }
}
public class JDKLIBDynamicProxy{
   public static void main(String[] args) {
       //真实明星
       Star kun = new RealStar("kun");
        //创建代理实例
        //loader:类加载器，用于加载代理对象。
        //interfaces被代理类实现的一些接口；
        //h：实现了vocationHandler接口的对象；
       Star proxy = (Star)Proxy.newProxyInstance(
               kun.getClass().getClassLoader(),
               kun.getClass().getInterfaces(),
               new StarAgentHandler(kun)
       );

       proxy.readLetter("I love you");
   }
}
